# -*- coding: utf-8 -*-
# This code written by ChanGOGOGO
"""
Lemon数据导出工具
"""
import sys
import time
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import QDateTime
from qfluentwidgets import (
    ComboBox,
    PushButton,
    PlainTextEdit,
    DateTimeEdit,
    EditableComboBox,
)
from util import *
from multithread_handle import (
    ExportExcel,
    ClientUpdate,
    ClassicQuote,
    QueryAccount,
    QueryDataType,
    QueryClientInteraction,
)


class Client(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.query_account = None
        self.query_business = None
        self.query_data_type = None
        self.query_client_interaction = None
        self.export_excel = None
        self.client_update_online = None
        self.classic_quote = None
        self.account_info = {}
        self.business_info = {}
        self.setFixedSize(550, 550)
        client_title = f"Lemon_{client_version}"
        self.setWindowTitle(client_title)
        self.setWindowIcon(QtGui.QIcon(f"{base_path}/icon/lemon.ico"))
        # 页面控件
        self.quote_label = QtWidgets.QLabel()
        data_date_label = QtWidgets.QLabel("拨打月份：")
        self.date_date_combo_box = ComboBox()
        last_twelve_months = get_last_twelve_months()
        self.date_date_combo_box.addItems(last_twelve_months)
        account_label = QtWidgets.QLabel("所属账号：")
        self.account_combo_box = EditableComboBox()
        self.account_combo_box.setPlaceholderText("请输入账号")
        self.account_combo_box.setMaxVisibleItems(10)
        business_label = QtWidgets.QLabel("业务名称：")
        self.business_combo_box = EditableComboBox()
        self.business_combo_box.setMaxVisibleItems(10)  # 设置下拉框单页展示可选项个数
        refresh_button = PushButton(
            "刷新", self, QtGui.QIcon(os.path.join(base_path, "icon/refresh.png"))
        )
        refresh_button.setToolTip("刷新")
        data_type_label = QtWidgets.QLabel("数据类型：")
        self.data_type_combo_box = EditableComboBox()
        self.data_type_combo_box.setMaxVisibleItems(8)
        call_type_label = QtWidgets.QLabel("拨打类型：")
        self.call_type_combo_box = ComboBox()
        self.call_type_combo_box.addItems(["呼出", "呼入"])
        task_type_label = QtWidgets.QLabel("任务类型：")
        self.task_type_combo_box = ComboBox()
        self.task_type_combo_box.setFixedWidth(130)
        self.task_type_combo_box.addItems(["活跃任务", "已完成任务"])
        start_time_label = QtWidgets.QLabel("开始时间：")
        self.start_time_edit = DateTimeEdit(self)
        self.start_time_edit.setFixedWidth(240)
        time_format = "yyyy-MM-dd hh:mm:ss"
        self.start_time_edit.setDisplayFormat(time_format)
        yesterday_button = PushButton(
            "昨天", self, QtGui.QIcon(os.path.join(base_path, "icon/left.png"))
        )
        today_button = PushButton(
            "今天", self, QtGui.QIcon(os.path.join(base_path, "icon/right.png"))
        )
        end_time_label = QtWidgets.QLabel("结束时间：")
        self.end_time_edit = DateTimeEdit(self)
        self.end_time_edit.setFixedWidth(240)
        self.end_time_edit.setDisplayFormat(time_format)
        last_month_button = PushButton(
            "上月", self, QtGui.QIcon(os.path.join(base_path, "icon/up.png"))
        )
        this_month_button = PushButton(
            "本月", self, QtGui.QIcon(os.path.join(base_path, "icon/down.png"))
        )
        self.target_data_label = QtWidgets.QLabel("目标数据：")
        self.target_data_plain_text_edit = PlainTextEdit()
        self.export_button = PushButton(
            "推送", self, QtGui.QIcon(os.path.join(base_path, "icon/push.png"))
        )
        self.export_button.setShortcut("F10")
        button_size_policy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
        )
        self.export_button.setSizePolicy(button_size_policy)
        self.msg_label = QtWidgets.QLabel("")
        # 控件交互
        self.date_date_combo_box.currentTextChanged.connect(self.data_date_changed)
        refresh_button.clicked.connect(self.refresh_all)
        self.account_combo_box.currentTextChanged.connect(self.refresh_business)
        self.data_type_combo_box.currentIndexChanged.connect(self.page_interaction)
        self.task_type_combo_box.currentIndexChanged.connect(self.page_interaction)
        self.start_time_edit.dateTimeChanged.connect(self.start_time_changed)
        yesterday_button.clicked.connect(self.set_yesterday)
        today_button.clicked.connect(self.set_today)
        last_month_button.clicked.connect(self.set_last_month)
        this_month_button.clicked.connect(self.set_this_month)
        self.export_button.clicked.connect(self.export_data)
        """页面布局"""
        client_grid = QtWidgets.QGridLayout(self)
        left_group_box = QtWidgets.QGroupBox()
        client_grid.addWidget(self.quote_label, 0, 0)
        client_grid.addWidget(left_group_box, 1, 0)
        left_layout = QtWidgets.QGridLayout(left_group_box)
        left_layout.addWidget(data_date_label, 0, 0, 1, 1)
        left_layout.addWidget(self.date_date_combo_box, 0, 1, 1, 5)
        left_layout.addWidget(account_label, 1, 0, 1, 1)
        account_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        left_layout.addWidget(self.account_combo_box, 1, 1, 1, 7)
        left_layout.addWidget(refresh_button, 1, 8, 1, 2)
        left_layout.addWidget(business_label, 2, 0, 1, 1)
        business_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        left_layout.addWidget(self.business_combo_box, 2, 1, 1, 5)
        left_layout.addWidget(data_type_label, 3, 0, 1, 1)
        left_layout.addWidget(self.data_type_combo_box, 3, 1, 1, 5)
        left_layout.addWidget(call_type_label, 4, 0, 1, 1)
        left_layout.addWidget(self.call_type_combo_box, 4, 1, 1, 1)
        left_layout.addWidget(task_type_label, 5, 0, 1, 1)
        left_layout.addWidget(self.task_type_combo_box, 5, 1, 1, 4)
        left_layout.addWidget(start_time_label, 6, 0, 1, 1)
        left_layout.addWidget(self.start_time_edit, 6, 1, 1, 7)
        left_layout.addWidget(yesterday_button, 6, 8, 1, 2)
        left_layout.addWidget(today_button, 6, 10, 1, 2)
        left_layout.addWidget(end_time_label, 7, 0, 1, 1)
        left_layout.addWidget(self.end_time_edit, 7, 1, 1, 7)
        left_layout.addWidget(last_month_button, 7, 8, 1, 2)
        left_layout.addWidget(this_month_button, 7, 10, 1, 2)
        left_layout.addWidget(self.target_data_label, 8, 0, 1, 1)
        self.target_data_label.setAlignment(
            QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter
        )
        left_layout.addWidget(self.target_data_plain_text_edit, 8, 1, 1, 10)
        left_layout.addWidget(self.export_button, 9, 1, 2, 2)
        client_grid.addWidget(self.msg_label, 2, 0)
        self.get_quete()  # 获取名句
        self.client_update()  # 在线检查更新
        self.refresh_account()  # 获取账号
        self.refresh_data_type()  # 获取数据类型
        # self.page_interaction()  # 页面交互

    def get_quete(self):
        """设置经典语句"""
        self.classic_quote = ClassicQuote()
        quote_content = self.classic_quote.get_hitokoto()
        self.quote_label.setText(quote_content)
        self.quote_label.setToolTip(quote_content)

    def client_update(self):
        """客户端在线更新"""
        self.client_update_online = ClientUpdate()
        self.client_update_online.start()
        self.client_update_online.msg.connect(self.echo_msg)

    def refresh_all(self):
        self.refresh_account()
        self.refresh_data_type()

    def refresh_account(self):
        """刷新'选择账号'下拉框可选项"""
        self.account_combo_box.clear()
        self.query_account = QueryAccount()
        try:
            self.account_info = self.query_account.query_account_info()
        except Exception as error:
            logging.error(error)
            self.echo_msg(
                f"<font color=red>查询账号信息异常，请联系@ChanGOGOGO！</font>"
            )
        if self.account_info:
            account_items = self.account_info.keys()
            account_completer = QtWidgets.QCompleter(account_items)
            account_completer.setFilterMode(QtCore.Qt.MatchFlag.MatchContains)
            self.account_combo_box.setCompleter(account_completer)
            self.account_combo_box.setClearButtonEnabled(True)

    def refresh_business(self):
        """刷新'业务名称'下拉框可选项"""
        self.business_combo_box.clear()
        current_account = self.account_combo_box.currentText()
        current_account_info = self.account_info.get(current_account)
        if current_account_info:  # 能找到账号，才同步更新“业务名称”下拉框可选项
            business_info = current_account_info.get("business_info")
            business_items = business_info.keys()
            self.business_combo_box.addItems(business_items)
            business_completer = QtWidgets.QCompleter(business_items)
            business_completer.setFilterMode(QtCore.Qt.MatchFlag.MatchContains)
            self.business_combo_box.setCompleter(business_completer)
            self.business_combo_box.setClearButtonEnabled(True)

    def refresh_data_type(self):
        self.data_type_combo_box.clear()
        self.query_data_type = QueryDataType()
        data_type = self.query_data_type.query_data_type()
        if data_type:
            self.data_type_combo_box.addItems(data_type)
            data_type_completer = QtWidgets.QCompleter(data_type)
            data_type_completer.setFilterMode(QtCore.Qt.MatchFlag.MatchContains)
            self.data_type_combo_box.setCompleter(data_type_completer)
            self.data_type_combo_box.setClearButtonEnabled(True)

    def page_interaction(self):
        client_data_type = self.data_type_combo_box.currentText()
        self.query_client_interaction = QueryClientInteraction(client_data_type)
        interaction_info = self.query_client_interaction.query_client_interaction()
        if interaction_info:
            if client_data_type == "未拨打数据":
                self.call_type_combo_box.setText("呼出")
                self.call_type_combo_box.setDisabled(True)
                self.task_type_combo_box.setDisabled(False)
                self.target_data_plain_text_edit.setDisabled(False)
                target_data = interaction_info.get("target_data")
                target_data_prompt = target_data.get("prompt")
                self.target_data_plain_text_edit.setPlaceholderText(
                    "\n".join(target_data_prompt)
                )
                client_task_type = self.task_type_combo_box.currentText()
                if client_task_type == "活跃任务":
                    self.date_date_combo_box.setDisabled(True)
                    self.start_time_edit.setDisabled(True)
                    self.end_time_edit.setDisabled(True)
                else:
                    self.date_date_combo_box.setDisabled(False)
                    self.start_time_edit.setDisabled(False)
                    self.end_time_edit.setDisabled(False)
                self.this_month()
                self.this_month_time()
            else:
                # 拨打月份
                call_month = interaction_info.get("call_month")
                call_month_disable = call_month.get("disable")
                self.date_date_combo_box.setDisabled(call_month_disable)
                # 拨打类型
                call_type = interaction_info.get("call_type")
                call_type_disable = call_type.get("disable")
                self.call_type_combo_box.setDisabled(call_type_disable)
                call_type_value = call_type.get("value")
                if call_type_value:
                    self.call_type_combo_box.setText(call_type_value)
                # 任务类型
                task_type = interaction_info.get("task_type")
                task_type_disable = task_type.get("disable")
                self.task_type_combo_box.setDisabled(task_type_disable)
                # 起止时间
                start_end_time = interaction_info.get("start_end_time")
                start_end_time_disable = start_end_time.get("disable")
                self.start_time_edit.setDisabled(start_end_time_disable)
                self.end_time_edit.setDisabled(start_end_time_disable)
                start_end_time_value = start_end_time.get("value")
                if start_end_time_value == "yesterday":
                    self.yesterday_time()
                elif start_end_time_value == "today":
                    self.today_time()
                elif start_end_time_value == "last_month":
                    self.last_month()
                    self.last_month_time()
                elif start_end_time_value == "this_month":
                    self.this_month()
                    self.this_month_time()
                target_data = interaction_info.get("target_data")
                target_data_disable = target_data.get("disable")
                self.target_data_plain_text_edit.setDisabled(target_data_disable)
                target_data_prompt = target_data.get("prompt")
                if target_data_prompt:
                    self.target_data_plain_text_edit.setPlaceholderText(
                        "\n".join(target_data_prompt)
                    )
                else:
                    self.target_data_plain_text_edit.setPlaceholderText("")
        else:
            # 拨打月份
            self.date_date_combo_box.setDisabled(False)
            # 任务类型
            self.task_type_combo_box.setDisabled(True)
            # 起止时间
            self.start_time_edit.setDisabled(False)
            self.end_time_edit.setDisabled(False)
            self.this_month()
            self.this_month_time()
            self.target_data_plain_text_edit.setPlaceholderText("")

    def yesterday_time(self):
        """设置开始时间为昨天"""
        time_format = "yyyy-MM-dd hh:mm:ss"
        yes_start_time = QDateTime.fromString(
            get_yes_start_time(), "yyyy-MM-dd hh:mm:ss"
        )
        yes_end_time = QDateTime.fromString(get_yes_end_time(), "yyyy-MM-dd hh:mm:ss")
        self.start_time_edit.setDateTime(yes_start_time)
        self.end_time_edit.setDateTime(yes_end_time)
        self.start_time_edit.setDisplayFormat(time_format)
        self.end_time_edit.setDisplayFormat(time_format)

    def today_time(self):
        """将开始时间设置为今天的0点，结束时间设置为今天的23:59:59"""
        time_format = "yyyy-MM-dd hh:mm:ss"
        today_start_time = QDateTime.fromString(
            get_today_start_time(), "yyyy-MM-dd hh:mm:ss"
        )
        today_end_time = QDateTime.fromString(
            get_today_end_time(), "yyyy-MM-dd hh:mm:ss"
        )
        self.start_time_edit.setDateTime(today_start_time)
        self.end_time_edit.setDateTime(today_end_time)
        self.start_time_edit.setDisplayFormat(time_format)
        self.end_time_edit.setDisplayFormat(time_format)

    def this_month_time(self):
        """将开始时间和结束时间设置为这个月的第一天0点和最后一天23:95:59"""
        time_format = "yyyy-MM-dd hh:mm:ss"
        str_start_time = get_current_month_start()
        str_end_time = get_today_end_time()
        start_time = QDateTime.fromString(str_start_time, "yyyy-MM-dd hh:mm:ss")
        end_time = QDateTime.fromString(str_end_time, "yyyy-MM-dd hh:mm:ss")
        self.start_time_edit.setDateTime(start_time)
        self.end_time_edit.setDateTime(end_time)
        self.start_time_edit.setDisplayFormat(time_format)
        self.end_time_edit.setDisplayFormat(time_format)

    def this_month(self):
        """设置数据月份为当前月，格式YYYYmm"""
        now_date = time.strftime("%Y%m")
        self.date_date_combo_box.setCurrentText(now_date)

    def last_month(self):
        """设置数据月份为上个月，格式YYYYmm"""
        last_month = get_last_month()
        self.date_date_combo_box.setCurrentText(last_month)

    def last_month_time(self):
        """将开始时间和结束时间设置为上个月的第一天0点和最后一天23:95:59"""
        time_format = "yyyy-MM-dd hh:mm:ss"
        str_start_time, str_end_time = get_last_month_start_end()
        start_time = QDateTime.fromString(str_start_time, "yyyy-MM-dd hh:mm:ss")
        end_time = QDateTime.fromString(str_end_time, "yyyy-MM-dd hh:mm:ss")
        self.start_time_edit.setDateTime(start_time)
        self.end_time_edit.setDateTime(end_time)
        self.start_time_edit.setDisplayFormat(time_format)
        self.end_time_edit.setDisplayFormat(time_format)

    def echo_msg(self, text):
        self.msg_label.setText(f"<font color=blue>{text}</font>")
        self.msg_label.setToolTip(f"<font color=blue>{text}</font>")

    def get_target_datas(self):
        target_data_text = self.target_data_plain_text_edit.toPlainText()
        target_datas = target_data_text.split("\n")
        finally_target_datas = []
        for target_data in target_datas:
            new_target_data = target_data.replace(" ", "")
            if new_target_data != "":
                finally_target_datas.append(new_target_data)
        return finally_target_datas

    def get_ui_data(self):
        ui_data = dict()
        ui_data["target_datas"] = (
            self.get_target_datas()
        )  # 目标数据：任务ID或者场景名称
        ui_data["data_date"] = self.date_date_combo_box.currentText()
        account = self.account_combo_box.currentText()
        business = self.business_combo_box.currentText()
        ui_data["business"] = business
        account_info = self.account_info.get(account)
        if account_info:
            ui_data["company_id"] = self.account_info.get(account).get("company_id")
            ui_data["business_id"] = (
                self.account_info.get(account).get("business_info").get(business)
            )
        else:
            ui_data["company_id"] = ""
            ui_data["business_id"] = ""
        ui_data["data_type"] = self.data_type_combo_box.currentText()
        ui_data["call_type"] = self.call_type_combo_box.currentText()
        ui_data["task_type"] = self.task_type_combo_box.currentText()
        ui_data["start_time"] = self.start_time_edit.text()
        ui_data["end_time"] = self.end_time_edit.text()
        return ui_data

    def start_time_changed(self):
        # 时间范围与数据月份联动
        start_time = self.start_time_edit.text()  # 开始时间值
        year = start_time[0:4]
        month = start_time[5:7]
        year_month = start_time[0:4] + start_time[5:7]
        self.date_date_combo_box.setCurrentText(year_month)
        _, month_end_time = get_month_start_end_time(year, month)

    def data_date_changed(self):
        """数据月份改变时，设置时间范围"""
        data_date = self.date_date_combo_box.currentText()
        year = data_date[0:4]
        month = data_date[4:6]
        month_start_time, month_end_time = get_month_start_end_time(year, month)
        month_start_time = QDateTime.fromString(month_start_time, "yyyy-MM-dd hh:mm:ss")
        current_start_time = self.start_time_edit.text()
        month_start_time_str = month_start_time.toString("yyyy-MM-dd HH:mm:ss")
        # 设置日期为昨天，可能导致数据月份变化了，因为月份变化会设置开始时间为月初第一天，这与设置开始时间为昨天0点有冲突
        if current_start_time[:7] == month_start_time_str[:7]:
            ...
        else:
            self.start_time_edit.setDateTime(month_start_time)
        month_end_time = QDateTime.fromString(month_end_time, "yyyy-MM-dd hh:mm:ss")
        self.end_time_edit.setDateTime(month_end_time)

    def verify_before_export(self):
        """界面控件只要是可以输入的，就必须输入"""
        data_date_availability = (
            self.date_date_combo_box.isEnabled()
        )  # 数据月份是否需要选择
        data_date = int(self.date_date_combo_box.currentText())  # 数据月份值
        data_type = self.data_type_combo_box.currentText()  # 数据类型值
        start_time_availability = (
            self.start_time_edit.isEnabled()
        )  # 时间范围的“开始时间”是否可编辑
        start_time = self.start_time_edit.text()  # 开始时间值
        start_date = start_time[0:10]
        start_month = int(start_time[0:4] + start_time[5:7])
        end_time_availability = (
            self.end_time_edit.isEnabled()
        )  # 时间范围的“结束时间”是否可编辑
        end_time = self.end_time_edit.text()  # 结束时间值
        end_date = end_time[0:10]
        end_month = int(end_time[0:4] + end_time[5:7])
        target_datas = self.get_target_datas()
        target_datas_availability = (
            self.target_data_plain_text_edit.isEnabled()
        )  # 任务ID是否需要输入
        # 如果需要输入任务ID，但是没有输入
        if (target_datas_availability is True) and (bool(target_datas) is False):
            if data_type == "未拨打数据":
                self.echo_msg("<font color=red>请输入任务ID！！！</font>")
                self.target_data_plain_text_edit.setFocus()
                return False
        # 数据月份必须和时间范围在同一个月，开始时间不得晚于结束时间
        if (
            (data_date_availability is True)
            and (start_time_availability is True)
            and (end_time_availability is True)
        ):
            if start_time > end_time:
                self.echo_msg("<font color=red>开始时间不得晚于结束时间！！！</font>")
                return False
            if start_month != end_month:
                self.echo_msg(
                    "<font color=red>开始时间和结束时间必须是同一个月！！！</font>"
                )
                return False
            if start_month != data_date:
                self.echo_msg(
                    "<font color=red>数据月份必须和时间范围在同一个月！！！</font>"
                )
                return False
            if data_type == "哈啰保险日报":
                if start_date != end_date:
                    self.echo_msg(
                        "<font color=red>哈啰保险日报开始时间、结束时间必须是同一天！！！</font>"
                    )
                    return False
        return True

    def export_data(self):
        ui_data = self.get_ui_data()
        self.export_excel = ExportExcel(ui_data)
        self.export_excel.start()
        self.export_excel.msg.connect(self.echo_msg)

    def set_yesterday(self):
        """"""
        self.yesterday_time()

    def set_today(self):
        self.today_time()

    def set_last_month(self):
        self.last_month_time()

    def set_this_month(self):
        self.this_month_time()


if __name__ == "__main__":
    QtWidgets.QApplication.setHighDpiScaleFactorRoundingPolicy(
        QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
    )
    QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle(QtWidgets.QStyleFactory.create("Fusion"))
    client = Client()
    client.show()
    sys.exit(app.exec_())
